package com.justgame.project.generator;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.config.ConstVal;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.justgame.project.generator.boot.IAutoGenerator;
import com.justgame.project.generator.properties.GlobalProperties;
import com.justgame.project.generator.properties.TemplateProperties;
import com.justgame.project.generator.schema.TableBuilder;
import com.justgame.project.generator.schema.TableSQLCreator;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.beanutils.BeanMap;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.stream.Collectors;

@Log4j2
@Component
public class CodeGeneratorRunner implements ApplicationRunner {
    private final IAutoGenerator autoGenerator;
    private final GlobalProperties globalProperties;
    private final TableBuilder tableBuilder;
    private final TemplateProperties templateProperties;

    public CodeGeneratorRunner(IAutoGenerator iAutoGenerator, GlobalProperties globalProperties, TableBuilder tableBuilder, TemplateProperties templateProperties) {
        this.autoGenerator = iAutoGenerator;
        this.globalProperties = globalProperties;
        this.tableBuilder = tableBuilder;
        this.templateProperties = templateProperties;
    }

    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append(tip + "：");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotBlank(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "！");
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        boolean doGenerator = true;
        if (globalProperties.getEnableAutoGenerator()) {
            log.info("正在自动生成代码：正在构建环境配置、数据实体等信息");
            tableBuilder.build();
            log.info("正在自动生成代码：正在执行模板代码生成");
            String[] tableNames = tableBuilder.getCreators().stream().map(TableSQLCreator::getTableName).toArray(String[]::new);
            autoGenerator.execute(tableNames);
            log.info("正在自动生成代码：正在构建SQL脚本环境信息");
            String outputSqlFilePath = globalProperties.getSqlFilePath();
            if (org.springframework.util.StringUtils.isEmpty(outputSqlFilePath)) {
                outputSqlFilePath = System.getProperty("user.dir");
            }
            String filePath = outputSqlFilePath + "/" + globalProperties.getSqlFileName();
            log.info("正在自动生成代码：正在批量生产SQL脚本，文件生成位置："+filePath);
            Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
            configuration.setDefaultEncoding(ConstVal.UTF8);
            configuration.setClassForTemplateLoading(FreemarkerTemplateEngine.class, "/");
            Template template = configuration.getTemplate(templateProperties.getSQLTemplatePath());
            FileOutputStream fileOutputStream = new FileOutputStream(filePath);
            Map<String, Object> objectMap = new HashMap<>();
            objectMap.put("tables",
                    tableBuilder.getCreators().stream().map(BeanMap::new).collect(Collectors.toList())
            );
            try {
                template.process(objectMap, new OutputStreamWriter(fileOutputStream, ConstVal.UTF8));
                log.info("正在自动生成代码：批量生产SQL成功！");
            } finally {
                fileOutputStream.close();
            }
        }else{
            while (doGenerator) {
                try {
                    String tableNames = scanner("请输入需要自动生成的表名( 多表用,号隔开 )");
                    System.out.println("表名如下：" + tableNames);
                    boolean sure = scanner("是否确认生成？('y' or any other)").toLowerCase().equals("y");
                    if (sure) {
                        autoGenerator.execute(tableNames.split(","));
                    }
                    doGenerator = scanner("是否继续？('y' or any other)").toLowerCase().equals("y");
                } catch (Exception e) {
                    log.error("代码生成异常", e);
                }
            }
        }
    }
}
